﻿namespace Tszy.Unlimited.Base.Http;

/// <summary>
/// 发起 HTTP 请求。
/// </summary>
public interface ITszyHttpClient
{
    /// <summary>
    /// HTTP GET 请求。
    /// </summary>
    /// <param name="path">地址（不带域名）</param>
    /// <param name="parameters">参数。</param>
    /// <returns></returns>
    public ITszyHttpRequestGet Get(string path, object? parameters = null);

    /// <summary>
    /// HTTP POST 请求。
    /// </summary>
    /// <param name="path">地址（不带域名）</param>
    /// <param name="parameters">参数。</param>
    /// <returns></returns>
    public ITszyHttpRequestPost Post(string path, object? parameters = null);

    /// <summary>
    /// HTTP POST JSON 请求。
    /// </summary>
    /// <param name="path">地址（不带域名）</param>
    /// <param name="parameters">参数。</param>
    /// <returns></returns>
    public ITszyHttpRequestPostJson PostJson(string path, object? parameters = null);
}

/// <summary>
/// 请求执行器。
/// </summary>
public interface ITszyHttpRequestExecutor
{
    /// <summary>
    /// 请求并返回结果。
    /// </summary>
    /// <returns></returns>
    Task<string> ExecuteAsync();

    /// <summary>
    /// 请求并返回实例。
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    Task<T> ExecuteAsync<T>();
}

/// <summary>
/// 请求信息设置。
/// </summary>
public interface ITszyHttpRequest<TRequest> : ITszyHttpRequestExecutor where TRequest : ITszyHttpRequest<TRequest>
{
    /// <summary>
    /// 设置请求头参数。
    /// </summary>
    /// <param name="name">参数名。</param>
    /// <param name="value">参数值。</param>
    /// <returns></returns>
    TRequest WithHeader(string name, object value);

    /// <summary>
    /// 设置请求头参数。
    /// </summary>
    /// <param name="headers"></param>
    /// <returns></returns>
    TRequest WithHeader(object headers);

    /// <summary>
    /// 设置请求头授权信息。
    /// </summary>
    /// <remarks>
    /// 会在请求头增加 Authorization = Basic XXX;
    /// </remarks>
    /// <param name="username"></param>
    /// <param name="password"></param>
    /// <returns></returns>
    TRequest WithBasicAuth(string username, string password);

    /// <summary>
    /// 设置请求头授权信息。
    /// </summary>
    /// <remarks>
    /// 会在请求头增加 Authorization = Bearer token;
    /// </remarks>
    /// <param name="token"></param>
    /// <returns></returns>
    TRequest WithOAuthBearerToken(string token);
}

/// <summary>
/// 设置 HTTP GET 请求。
/// </summary>
public interface ITszyHttpRequestGet : ITszyHttpRequest<ITszyHttpRequestGet>
{
    /// <summary>
    /// 设置 HTTP GET 请求参数。
    /// </summary>
    /// <param name="query">请求参数。</param>
    /// <returns></returns>
    ITszyHttpRequestExecutor SetParameters(object query);
}

/// <summary>
/// 设置 HTTP POST 请求。
/// </summary>
public interface ITszyHttpRequestPost : ITszyHttpRequest<ITszyHttpRequestPost>
{
    /// <summary>
    /// 设置 HTTP POST 请求参数。
    /// </summary>
    /// <param name="query">请求参数。</param>
    /// <returns></returns>
    ITszyHttpRequestExecutor SetParameters(object query);

    /// <summary>
    /// 增加文件。
    /// </summary>
    /// <param name="parameterName">参数名。</param>
    /// <param name="data">文件流。</param>
    /// <param name="fileName">文件名（带后缀名）</param>
    /// <param name="contentType"></param>
    /// <param name="bufferSize"></param>
    /// <returns></returns>
    ITszyHttpRequestPostJson AddFile(string parameterName, Stream data, string fileName, string? contentType = null, int bufferSize = 4096);

    /// <summary>
    /// 增加文件。
    /// </summary>
    /// <param name="parameterName">参数名。</param>
    /// <param name="path">文件完整路径（包含文件名与后缀名）。</param>
    /// <param name="contentType"></param>
    /// <param name="bufferSize"></param>
    /// <returns></returns>
    ITszyHttpRequestPostJson AddFile(string parameterName, string path, string? contentType = null, int bufferSize = 4096);
}

/// <summary>
/// 设置 HTTP POST JSON 请求。
/// </summary>
public interface ITszyHttpRequestPostJson : ITszyHttpRequest<ITszyHttpRequestPostJson>
{
    /// <summary>
    /// 设置 HTTP POST JSON 请求参数。
    /// </summary>
    /// <param name="query">请求参数。</param>
    /// <returns></returns>
    ITszyHttpRequestExecutor SetParameters(object query);
}